package com.bankcomm.luafuction;

import java.io.File;
import java.util.ArrayList;
import java.util.Stack;
import java.util.Timer;
import org.keplerproject.luajava.LuaException;
import org.keplerproject.luajava.LuaObject;
import org.keplerproject.luajava.LuaState;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.text.TextUtils;
import com.bankcomm.common.ConfigManager;
import com.bankcomm.common.LPMid;
import com.bankcomm.ui.EMPView;
import com.rytong.tools.clienthello.ClientHello;
import com.rytong.tools.crypto.Base64;
import com.rytong.tools.datastorage.PackageManagerAndroid;
import com.rytong.tools.httpconnect.HttpManager;
import com.rytong.tools.httpconnect.WaitDialog;
import com.rytong.tools.ui.AtomParser;
import com.rytong.tools.ui.BaseView;
import com.rytong.tools.ui.Component;
import com.rytong.tools.ui.ComponentCopy;
import com.rytong.tools.utils.Utils;

public class LuaUtility {
    public int arraySize_;

    public ArrayList array_;
    private Timer timer_;

    public LuaUtility() {

        // TODO Auto-generated constructor stub
        try {
            Component.LUASTATE.pushObjectValue(this);
            Component.LUASTATE.setGlobal("luautility");
            final String luahead = "utility = {}; ";
            final String luafc1 = "function utility:tls(object,callback) luautility:tls(object,callback); end;";
            final String luafc2 = "function utility:base64Encode(name) local a1 = luautility:base64Encode(name); return a1; end;";
            final String luafc3 = "function utility:escapeURI(name) local a1 = luautility:escapeURI(name); return a1; end;";
            final String luafc4 = "function utility:post(url, body, callback, synchronous) luautility:post(url, body, callback, synchronous) end;";
            final String luafc5 = "function utility:trim(name) local a1 = luautility:trim(name); return a1; end;";
            final String luafc6 = "function utility:passwordEncryption(passwords,modes,callback) luautility:passwordEncryption(passwords,modes,callback); end;";
            final String luafc7 = "function utility:escapeURL(name) local a1 = luautility:escapeURI(name); return a1; end;";
            final String luafc8 = "function utility:base64Decode(name) local a1 = luautility:base64Decode(name); return a1; end;";
            final String luafc9 = "function utility:unescapeURI(name) local a1 = luautility:unescapeURI(name); return a1; end;";
            final String luafc10 = "function utility:length(name) local a1 = luautility:length(name); return a1; end;";
            final String luafc11 = "function utility:callPhone(number) local a1 = luautility:callPhone(number); return a1; end;";
            final String luafc12 = "function utility:openProgram(url,packageName,className) luautility:openProgram(url,packageName,className); end;";
            final String luafc13 = "function utility:isInstalled(packageName) local a1 = luautility:isInstalled(packageName); return a1; end;";
            Component.LUASTATE.gc(LuaState.LUA_GCCOLLECT, 0);
            Component.LUASTATE.LdoString(luahead.concat(luafc1).concat(luafc2).concat(luafc3).concat(luafc5)
                    .concat(luafc6).concat(luafc7).concat(luafc8).concat(luafc9).concat(luafc10).concat(luafc11).concat(luafc12).concat(luafc13));
        } catch (Exception e) {
            Utils.printException(e);
        }
    }

    /**
     * 
     * @param passwords
     *            passwords类型为table，可将要加密的密码存入其中，可传多个密码，例?��：{pass1="123123",pass2="123456"}
     * 
     * @param modes
     *            modes类型为table，可存入密码的加密模式，模式与密码要统一key。例如：{pass1="AE1",pass2="A1"}
     * 
     * @param callback
     *            callback为回调函数，客户端加密成功后调用回调函数，该回调函数的参数是table�??��，用来存储加密后的密码，格式�?{pass1="GDFGGDFG345543",pass2=
     *            "DFGSDFG345DFGDFG"}
     */
    public void passwordEncryption(LuaObject passwords, LuaObject modes, LuaObject callback) {
        passwords.push();
        // 循环读取table中的属性�?
        Component.LUASTATE.pushNil();
        ArrayList alKeyP = new ArrayList(2);
        ArrayList alValueP = new ArrayList(2);
        String keyString = "";
        String valueString = "";
        while (Component.LUASTATE.next(-2) != 0) {
            keyString = "";
            if (Component.LUASTATE.type(-2) == Component.LUASTATE.LUA_TNUMBER) {
                keyString = Double.toString(Component.LUASTATE.toNumber(-2));
            } else if (Component.LUASTATE.type(-2) == Component.LUASTATE.LUA_TSTRING) {
                keyString = Component.LUASTATE.toString(-2);
            }
            valueString = "";
            if (Component.LUASTATE.type(-1) == Component.LUASTATE.LUA_TNUMBER) {
                valueString = Double.toString(Component.LUASTATE.toNumber(-1));
            } else if (Component.LUASTATE.type(-1) == Component.LUASTATE.LUA_TSTRING) {
                valueString = Component.LUASTATE.toString(-1);
            } else if (Component.LUASTATE.type(-1) == Component.LUASTATE.LUA_TTABLE) {
            }

            alValueP.add(valueString);
            alKeyP.add(keyString);
            Component.LUASTATE.pop(1);
        }
        Component.LUASTATE.pop(2);

        modes.push();
        // 循环读取table中的属性�?
        Component.LUASTATE.pushNil();
        ArrayList alKeyM = new ArrayList(2);
        ArrayList alValueM = new ArrayList(2);
        while (Component.LUASTATE.next(-2) != 0) {
            keyString = "";
            if (Component.LUASTATE.type(-2) == Component.LUASTATE.LUA_TNUMBER) {
                keyString = Double.toString(Component.LUASTATE.toNumber(-2));
            } else if (Component.LUASTATE.type(-2) == Component.LUASTATE.LUA_TSTRING) {
                keyString = Component.LUASTATE.toString(-2);
            }
            valueString = "";
            if (Component.LUASTATE.type(-1) == Component.LUASTATE.LUA_TNUMBER) {
                valueString = Double.toString(Component.LUASTATE.toNumber(-1));
            } else if (Component.LUASTATE.type(-1) == Component.LUASTATE.LUA_TSTRING) {
                valueString = Component.LUASTATE.toString(-1);
            } else if (Component.LUASTATE.type(-1) == Component.LUASTATE.LUA_TTABLE) {
            }

            alValueM.add(valueString);
            alKeyM.add(keyString);
            Component.LUASTATE.pop(1);
        }
        Component.LUASTATE.pop(2);

        ArrayList value = new ArrayList(alKeyP.size());
        int size = alKeyP.size();
        Component.IVTEMP = null;
        Component.KEYTEMP = null;
        try {
            for (int i = 0; i < size; i++) {
            	String v = Component.encryptValue((String) alValueM.get(i), (String) alValueP.get(i), null);
            	String enV = Utils.escapeURIComponent(v);
            	value.add(enV);
            }

            // 创建一个table
            Component.LUASTATE.newTable();
            LuaObject table = Component.LUASTATE.getLuaObject(-1);
            Component.LUASTATE.pop(1);
            // 将约定的固有参数压入表中
            table.push();
            for (int i = 0; i < size; i++) {
                Component.LUASTATE.pushObjectValue(alKeyP.get(i));
                Component.LUASTATE.pushObjectValue(value.get(i));
                Component.LUASTATE.setTable(-3);
            }
            Component.LUASTATE.pop(1);

            Object[] args = new Object[1];
            args[0] = table;
            callback.call(args, 0);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            Utils.printException(e);
        }

    }

    /**
     * 执行加密通道?��系列?��???
     */
    public void tls(final LuaObject table, final Object callObject) {
        EMPView.mid_.waitDialog_.addFgTask(ConfigManager.currentView_, null, 0, 0, 0, new WaitDialog.Task(0) {
            ClientHello ch;

            @Override
            public void run(WaitDialog dlg) {
                // TODO Auto-generated method stub
                String temp = getLuaTable(table);
                try {
                    ch = new ClientHello(ConfigManager.currentView_, ConfigManager.SERVER_URI,
                            EMPView.mid_.midletVersion_, ConfigManager.CLIENT_HELLO, ConfigManager.CLIENT_KEY_EXCHANGE,
                            ConfigManager.CLIENT_FACILITY_HELLO, EMPView.CERTIFICATE, temp);
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    Utils.printException(e);
                }
            }

            public void onSuccess(WaitDialog dlg) {
            	if(HttpManager.isAppUpgrading){
            		exitSystem("服务升级中，请稍后再试 !");
            	} else {
            		try {
            		    // 执行回调方法
            		    if (callObject != null && callObject instanceof LuaObject) {
            		        LuaObject luaObject = (LuaObject) callObject;
            		        if (luaObject.isFunction()) {
            		            luaObject.call(null);
            		        }
            		                         }
            		    // 建立加密通道以�??,需要将界面�??��加�??�?界面堆栈�?
            		    if (null == Component.ACTIONV)
            		        Component.ACTIONV = new Stack();
            		    AtomParser apc = new AtomParser(ConfigManager.currentView_, AtomParser.ENTIRE);
            		    String reply = Utils.unescapeHTML(ch.getText());
            		    reply = Utils.insteadOfSpecillCharacter(reply, true);
            		    Component.ACTIONV.add((String) reply);
            		    android.util.Xml.parse(reply, apc);
            		    ConfigManager.currentView_.runOnUiThread(new Runnable() {
            		        @Override
            		        public void run() {
            		            ConfigManager.currentView_.setContentView(ComponentCopy.COMPONENT.getLPView());
            		        }
            		    });
            		    // 存储后台??�要�??是否第一次启动参�?
            		    String isfirst = PackageManagerAndroid.ANDROIDDB.get(PackageManagerAndroid.ISFIRST_DB);
            		    int index = 1;
            		    if (null == isfirst || isfirst.equals("")) {
            		    } else {
            		        index = Integer.parseInt(isfirst);
            		        index++;
            		    }
            		    isfirst = String.valueOf(index);
            		    PackageManagerAndroid.ANDROIDDB.save(PackageManagerAndroid.ISFIRST_DB, isfirst);
            		    super.onSuccess(dlg);
            		    // 下载离线资源
            		    BaseView.OFFSTORED.downloadOfflineResource(ConfigManager.SERVER_URI);
            		} catch (final Exception e) {
            		    Utils.printException(e);
            		    super.onSuccess(dlg);
            		    if (e.toString().contains(".NullPoi"))
            		        exitSystem(Utils.getConfigStringFormAsset(Utils.getActivity(), "httpError"));
            		    else
            		        exitSystem(e.toString());
                    }
            	}
            }

            public void onFailure(WaitDialog dlg) {
                super.onFailure(dlg);
                exitSystem(getErrMsg());
            }

        });
    }

    protected String getLuaTable(LuaObject table) {
        // TODO Auto-generated method stub
        if (null == table)
            return "";
        table.push();
        // 循环读取table中的属性�?
        Component.LUASTATE.pushNil();
        String keyString = "";
        String valueString = "";
        String temp = "";
        while (Component.LUASTATE.next(-2) != 0) {
            keyString = "";
            if (Component.LUASTATE.type(-2) == Component.LUASTATE.LUA_TNUMBER) {
                keyString = Double.toString(Component.LUASTATE.toNumber(-2));
            } else if (Component.LUASTATE.type(-2) == Component.LUASTATE.LUA_TSTRING) {
                keyString = Component.LUASTATE.toString(-2);
            }
            valueString = "";
            if (Component.LUASTATE.type(-1) == Component.LUASTATE.LUA_TNUMBER) {
                valueString = Double.toString(Component.LUASTATE.toNumber(-1));
            } else if (Component.LUASTATE.type(-1) == Component.LUASTATE.LUA_TSTRING) {
                valueString = Component.LUASTATE.toString(-1);
            } else if (Component.LUASTATE.type(-1) == Component.LUASTATE.LUA_TTABLE) {
            }

            temp = temp.concat("&").concat(keyString).concat("=").concat(valueString);
            Component.LUASTATE.pop(1);
        }
        Component.LUASTATE.pop(2);

        return temp;
    }

    protected void exitSystem(String string) {
        // TODO Auto-generated method stub
        final Builder ad = new AlertDialog.Builder(ConfigManager.currentView_);
        ad.setTitle("提示").setMessage(string).setCancelable(false)
                .setNegativeButton("确定", new DialogInterface.OnClickListener() {

                    public void onClick(DialogInterface dialog, int which) {
                        // TODO Auto-generated method stub

                        // 停止程序开启的服务，保证程序退出后不会常驻内存
                        Intent intent = new Intent();
                        intent.setAction(getClass().getPackage().getName());
                        ConfigManager.currentView_.stopService(intent);
                        System.exit(0);

                    }

                });
        if (!ConfigManager.currentView_.isFinishing()) {
            ConfigManager.currentView_.runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    ad.show();
                }
            });

        }
    }

    public String trim(String str) {
        return str != null ? str.trim() : null;
    }

    public String base64Encode(String str) {
        return Base64.encode(str.getBytes());
    }

    public String base64Decode(String str) {
        return Base64.decodeToString(str);
    }

    public String escapeURI(String str) {
        return Utils.escapeURIComponent(str);
    }

    public String unescapeURI(String str) {
        return Utils.unescapeURIComponent(str);
    }

    /**
     * 
     * @param url
     *            连接网络的地址
     * @param body
     *            传输的具体内?��,可以为空
     * @param callback
     *            回调的方�?用于异步传输
     * @param synchronous
     *            是否用同步还是异步传�?此处有别于iphone,android用的都是异步传输
     */
    public void post(final String url, final String body, final Object callback, boolean synchronous) {
        LPMid.getInstance().waitDialog_.addFgTask(ConfigManager.currentView_, null, 0, 0, 0, new WaitDialog.Task(0) {

            @Override
            public void run(WaitDialog arg0) throws Exception {
                // TODO Auto-generated method stub
                String reply = (String) LPMid.getInstance().hm_.sendPostRequest(
                        ConfigManager.SERVER_URI.concat((String) url), body, this, null, null);
                if (null != reply) {
                    // 如果存在返回�?则调用Lua脚本中的callback方法,�?将reply作为一个参数传递给该方�?
                    setParamsToLuaFuction((LuaObject) callback, reply);
                }
            }
        });
    }

    public Object getElementAt(int index) {
        if (null != array_ && array_.size() > 0)
            return array_.get(index);
        return null;
    }

    /**
     * 
     * @param callback
     *            需要执行的lua脚本方法
     * @param reply
     *            需要传递的参数，一般为联网后获取的服务端报�?
     */
    protected void setParamsToLuaFuction(LuaObject callback, String reply) {
        // TODO Auto-generated method stub
        if (callback.isFunction()) {
            // 如果是lua则将参数代入?��执行并执�?
            try {
                callback.call(new Object[] { reply }, 0);
            } catch (LuaException e) {
                // TODO Auto-generated catch block
                Utils.printException(e);
            }
        }
    }

    public int length(String str) {
        if (str != null)
            return str.length();
        else
            return -1;
    }
    
    /**
     * 
     * word \ excel \ ppt \ pdf
     * */
    public void openOfficeFile(String path , String  type){
    	if(TextUtils.isEmpty(path) || TextUtils.isEmpty(type)){
    		return ;
    	}
    	try{
    		Intent intent  = new Intent("android.intent.action.VIEW");
    		intent.addCategory("android.intent.category.DEFAULT");
    		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    		
    		Uri uri = Uri.fromFile(new File(path));
    		
    		if(type.equalsIgnoreCase("word")){
    			intent.setDataAndType(uri, "application/msword");
        	} else if(type.equalsIgnoreCase("excel")){
        		intent.setDataAndType(uri, "application/vnd.ms-excel");
        	} else if(type.equalsIgnoreCase("ppt")){
        		intent.setDataAndType(uri, "application/msword");
        	} else if(type.equalsIgnoreCase("pdf")){
        		intent.setDataAndType(uri , "application/pdf");
        	} 
    		
    		ConfigManager.currentView_.startActivity(intent);
    	}catch(Exception e){
    		Utils.printException(e);
    	}
    }
    
    /**
     * 判断是否安装应用程序
     * @param packageName
     * @return
     */
    public String isInstalled(String packageName){
    	if(null != ConfigManager.currentView_){
    		if(Utils.isInstalled(ConfigManager.currentView_, packageName)){
    			return "true";    		
    		}
    	}
    	return "false";
    }
    
    /**
     * 启动第三方应用，如果该应用不存在，则跳转到下载地址
     * @param url 下载地址
     * @param packageName 应用包名
     * @param className 应用类名 
     */
    public void openProgram(String url,String packageName,String className){
    	if(null != ConfigManager.currentView_){
    		if(null != packageName && !"".equalsIgnoreCase(packageName) && Utils.isInstalled(ConfigManager.currentView_, packageName)){
    			PackageManager packageManager = ConfigManager.currentView_.getPackageManager();  
    			Intent intent = new Intent(); 
    			if(null != className && !"".equalsIgnoreCase(className)){
    				//启动应用，存在类名
    				ComponentName componentName =new   ComponentName(packageName,packageName+"."+className);   
                    intent.setComponent(componentName);   
                    intent.setAction(Intent.ACTION_VIEW);   
    			}else{
    				try {  
    					//启动应用，没有类名
    					intent = packageManager.getLaunchIntentForPackage(packageName);  
    				} catch (Exception e) {
    					e.printStackTrace();
    				}  
    			}
    			ConfigManager.currentView_.startActivity(intent); 
    		}else{
    			if(null != url && !"".equalsIgnoreCase(url)){
    				ConfigManager.currentView_.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
    			}
    		}
    	}
    }
    
    /**
     * do a call 拨打电话
     * @param phoneNumber
     */
    public void callPhone(String phoneNumber){
    	if(null != phoneNumber && !"".equalsIgnoreCase(phoneNumber)){
    		//拨打电话
    		Intent telIntent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phoneNumber));
    		if(null != ConfigManager.currentView_){
    			ConfigManager.currentView_.startActivity(telIntent);    			
    		}
    	}
    }
}
